package Saveable;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL12;

import org.lwjgl.opengl.GL11;

public class GLImage implements Serializable {

	private static final long serialVersionUID = 1L;
	private byte[] ImageData;
	private int ImgWidth;
	private int ImgHeight;
	private int ImgWrapX = 1;
	private int ImgWrapY = 1;
	private transient int glImgIndex;
	//private transient BufferedImage BuffImage;

	public GLImage(String path) {
		BufferedImage image = null;
		try {
			image = ImageIO.read(new File(path));
		} catch(IOException e){System.out.println(e);}
		ImgHeight = image.getHeight();
		ImgWidth = image.getWidth();
		if (ImgHeight <= 0) ImgHeight = 1;
		if (ImgWidth <= 0) ImgWidth = 1;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			ImageIO.write(image, "png", os);
		} catch (IOException e) {
			e.printStackTrace();
		}
		ImageData = os.toByteArray();
	}
	
	private BufferedImage getImage() {
		InputStream image = null;
		image = new ByteArrayInputStream(ImageData);
		BufferedImage buff = new BufferedImage(ImgWidth, ImgHeight, BufferedImage.TYPE_INT_ARGB);
		try {
			buff = ImageIO.read(image);
			return buff;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void setup() {   
        BufferedImage image = getImage();
        int[] pixels = new int[ImgWidth * ImgHeight];
        image.getRGB(0, 0, ImgWidth, ImgHeight, pixels, 0, ImgWidth);
        ByteBuffer buffer = BufferUtils.createByteBuffer(ImgWidth * ImgHeight * 4); //4 for RGBA, 3 for RGB
        for (int y = 0; y < ImgHeight; y++) {
            for (int x = 0; x < ImgWidth; x++) {
                int pixel = pixels[y * ImgWidth + x];
                buffer.put((byte) ((pixel >> 16) & 0xFF));     // Red component
                buffer.put((byte) ((pixel >> 8) & 0xFF));      // Green component
                buffer.put((byte) (pixel & 0xFF));               // Blue component
                buffer.put((byte) ((pixel >> 24) & 0xFF));    // Alpha component. Only for RGBA
            }
        }
        buffer.flip();
        glImgIndex = GL11.glGenTextures(); //Generate texture ID
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glImgIndex); //Bind texture ID
        //Setup wrap mode
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
        //Setup texture scaling filtering
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        //Send texel data to OpenGL
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, ImgWidth, ImgHeight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
        //glPixelTransferf(GL_ALPHA_BIAS, 0);
		
	}

	public void setWrapping(int X, int Y) {
		ImgWrapX = X;
		ImgWrapY = Y;
	}

	public int getImageIndex() {
		return glImgIndex;
	}

	public int getWidth() {
		return ImgWidth;
	}

	public int getHeight() {
		return ImgHeight;
	}

	public int getWrapX() {
		return ImgWrapX;
	}

	public int getWrapY() {
		return ImgWrapY;
	}
	
}
